//
//  LBRViewController.m
//  LBReact
//
//  Created by WuShiHai on 19/5/24.
//  Copyright (c) 2019 Lebbay. All rights reserved.
//

#import "LBRViewController.h"
#import <React/RCTBundleURLProvider.h>
#import "LBReactBridge.h"
#import <React/RCTRootView.h>
#import <LBUIKit/LBUIKit.h>
#import <LBFoundation/LBFoundation.h>

NSString *const LBRChangeStatusBarStyleNotification = @"LBRChangeStatusBarStyleNotification";
NSString *const LBJavaScriptWillStartLoadingModuleNotification = @"LBJavaScriptWillStartLoadingModuleNotification";
NSString *const LBJavaScriptDidLoadingModuleNotification = @"LBJavaScriptDidLoadingModuleNotification";

static NSString *randomStringWithLength(NSInteger len) {
    NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
    
    for (NSInteger i = 0; i < len; i++) {
        [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform((uint32_t)[letters length])]];
    }
    return randomString;
}

@interface LBRStatusBarMode : NSObject

@property (nonatomic, strong) NSString *style;
@property (nonatomic, strong) NSString *moduleId;

@end

@implementation LBRStatusBarMode

- (UIStatusBarStyle)statusBarStyle {
    return [self.style isEqualToString:@"light"] ? UIStatusBarStyleLightContent : UIStatusBarStyleDefault;
}

@end

@interface LBRViewController ()

@property (nonatomic, strong) RCTRootView *rootView;

@property (nonatomic, assign) LBReactPageType *pageType;

@property (nonatomic, strong) NSString *moduleId;

@property (nonatomic, assign) BOOL isExist;

@property (nonatomic, assign) UIStatusBarStyle lbr_statusBarStyle;

@end

@implementation LBRViewController

- (instancetype)initWithURL:(NSString *)URLString
                  component:(NSString *)component
                   userInfo:(NSDictionary *)userInfo {
    
    NSString *moduleId = randomStringWithLength(8);
    NSMutableDictionary *mergeUserInfo = [NSMutableDictionary dictionaryWithDictionary:userInfo];
    [mergeUserInfo setValue:moduleId forKey:@"moduleId"];
    component ? [mergeUserInfo setValue:component forKey:@"module"] : nil;
    
    if (self = [self init]) {
        _componentName = component;
        _moduleId = moduleId;
        _userInfo = [mergeUserInfo copy];
        _pageType = [self pageTypeFrom:userInfo];
        _lbr_statusBarStyle = UIStatusBarStyleDefault;
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(javaScriptDidLoad)
                                                     name:LBJavaScriptDidLoadAppNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(changeStatusBarStyle:)
                                                     name:LBRChangeStatusBarStyleNotification
                                                   object:nil];
    }
    
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.view.backgroundColor = [UIColor whiteColor];
    
    if (LBReactBridgeManagerMode == LBReactBridgeMultiMode) {
        [self renderInMultiMode:_componentName];
    } else {
        [self loadComponent];
    }
}

- (void)render:(NSString *)component
      userInfo:(NSDictionary *)userInfo {
    
    _componentName = component;
    _userInfo = userInfo;
    [self loadComponent];
}

- (void)renderInMultiMode:(NSString *)component {}

- (void)loadComponent {
    if (self.isViewLoaded == NO) {
        return;
    }

    LBReactBridge *manager = [LBReactBridge manager];
    LBBridge *bridge = LBReactBridgeManagerMode == LBReactBridgeMultiMode ?
    self.bridge : [LBReactBridgeManager bridge];    
    if (bridge != nil
        && self.componentName.length > 0) {
        self.bridge = bridge;
        [self.rootView removeFromSuperview];
        
        //首次通过该方法加载brdige，之后通过RCTRootView中自带的监听方法加载
        RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                         moduleName:self.componentName
                                                  initialProperties:self.userInfo];
        self.rootView = rootView;
        
        rootView.frame = CGRectMake(0,
                                    0,
                                    SCREEN_WIDTH,
                                    SCREENH_HEIGHT - ([self isShowTabBar] ? IPHONE_TAB_BAR_HEIGHT : 0));
        rootView.backgroundColor = [UIColor whiteColor];
  
        [self.view addSubview:rootView];
    }
}

- (BOOL)isShowTabBar {
    NSArray *viewControllers = self.tabBarController.viewControllers;
    if ([viewControllers count] > 0
        && ([viewControllers containsObject:self]
            ||([viewControllers containsObject:self.navigationController]
               && [self.navigationController.viewControllers indexOfObject:self] == 0))) {
        return YES;
    }
    return NO;
}

- (BOOL)isRegisterComponent:(NSString *)component {
    return [self.bridge isContainCompnent:component];
}

#pragma mark - Notification
- (void)javaScriptDidLoad {
    if ([LBReactBridge manager].mode == LBReactBridgeServerMode) {
        //RCTRootView 会自己监听事件
        if (self.rootView == nil) {
            [self loadComponent];
        }
    } else if ([LBReactBridge manager].mode == LBReactBridgeSingleMode) {
        //非server 模式 每次会重新生成bridge rootView无法监听通知，故这里监听
        [self loadComponent];
    }
}

- (void)changeStatusBarStyle:(NSNotification *)notification {
    NSDictionary *userInfo = notification.object;
    LBRStatusBarMode *mode = [LBRStatusBarMode yy_modelWithJSON:userInfo];
    if ([mode.moduleId isEqualToString:self.moduleId]) {
        self.lbr_statusBarStyle = [mode statusBarStyle];
        [self setNeedsStatusBarAppearanceUpdate];
    }
}

#pragma mark - Private
- (LBReactPageType)pageTypeFrom:(NSDictionary *)userInfo {
    NSInteger rt = [[userInfo objectForKey:@"rt"] integerValue];
    if (rt == 1) {
        return LBReactPageTypeCore;
    } else if (rt == 2) {
        return LBReactPageTypeActivity;
    } else {
        return LBReactPageTypeDefault;
    }
}

#pragma mark - Override
- (UIStatusBarStyle)preferredStatusBarStyle {
    return self.lbr_statusBarStyle;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end
